package server;

import java.io.*;
import java.util.*;

/**
 * @author Will
 *	the TXN class record the transaction information
 */
public class TXN implements Serializable{
	private static final long serialVersionUID = 794836013779061074L;	
	  int TXNID;
	  String command;
	  String filePath;
	  String fileName;	
	  
	  int totalNumber;  
//	  String receivedSequence;	  
	  
	  //build a new hash table to store the sequence and its corresponding message
	  Map<String, String> dataMapToDisk; 
	  
	 /**
	 * @param id - the transaction id
	 * @param fileName - the transaction filename
	 */

	TXN(int id,String command,String filePath,String fileName){
		TXNID=id;
		totalNumber=0;
		this.filePath=filePath;
		this.fileName=fileName;
		this.command=command;
		
		//build a new hash table to store the sequence and its corresponding message
		dataMapToDisk=new HashMap<String,String>(); 
	  }
	
	@Override
	public String toString(){
		return new StringBuffer("TXNID: ").append(this.TXNID)
		.append("; command: ").append(this.command)
		.append("; filePath: ").append(this.filePath)
		.append("; fileName: ").append(this.fileName)
		.append("; totalNumber: ").append(this.totalNumber)
		.append("; dataMapToDisk: ").append(this.dataMapToDisk)
		.toString();  
	  }	
	
	public void writeLog(){
		// to store the log in file system, file name is TXNID, using "." to hide the log
		try{
			File toFile=new File(filePath,"."+(new Integer(TXNID).toString()+".log"));
		if(toFile.canRead()!=true){
			//cannot open the file, so create a new file and set the createdAFile tag
			toFile.createNewFile();	
		}		
		FileOutputStream fout= new FileOutputStream(toFile);		
		ObjectOutputStream oos=new ObjectOutputStream(fout);
		oos.writeObject(this);
		oos.close();	
		}catch(Exception ex){
		   ex.printStackTrace();
		   System.out.println("Cannot write log.!!!");
		} 		
		return ;	
	}

	//ready to use
	public TXN readLog(int txn_id){
		TXN txn;
		try{
			File toFile=new File(filePath,"."+(new Integer(txn_id).toString()+".log"));
			FileInputStream fin= new FileInputStream(toFile);		
			ObjectInputStream input=new ObjectInputStream(fin);
			txn=(TXN)input.readObject();
			System.out.println("reading:");
			System.out.println(txn);
		   return txn;
 
	   }catch(Exception ex){
		   ex.printStackTrace();
		   System.out.println("Cannot reading log.!!!");
		   return null;
		   } 
	}
	
	public void delelteLog(){
		File toDeleteFile=new File(filePath,"."+(new Integer(TXNID).toString()+".log"));
		toDeleteFile.delete();
		return ;
	}
	
	public void commit() throws IOException{				
		File toFile= new File(filePath,fileName);		
		if(toFile.canRead()!=true){
		//cannot open the file, so create a new file and set the createdAFile tag
			toFile.createNewFile();
		}
		// flush to file system, it add to the end of the file
		FileWriter fw = new FileWriter(toFile,true);
		BufferedWriter bw=new BufferedWriter(fw);
		String temp;
		for(int i=0;i<totalNumber;i++){
			temp=(new Integer(i).toString());
			bw.write(dataMapToDisk.get(temp));	
		}
		bw.flush();
		bw.close();
		return ;
	}//end flush()
	
	public void addData(String seqNum, String append){
		dataMapToDisk.put(seqNum, append+"\n");
		totalNumber = dataMapToDisk.size();
		return ;
	}
	
	public String findResendSeq(int totalSeq){
		String resendSeq = "";		
		String temp;
		for(int i=0;i<totalSeq;i++){
			temp=(new Integer(i).toString());
			if(dataMapToDisk.get(temp) == null){
				resendSeq = resendSeq + temp + " ";
			}
		}		
        return resendSeq;
	}//end findResendSeq
}

//public static void main (String args[]) {
//TXN txn = new TXN(0,"test","./","file.txt");			  
//try {
//	  txn.addData("0", "hello");
//	  txn.addData("1", "world");
//	  txn.addData("2", "-_-");
//	  txn.writeLog();
//	  txn.commit();
//	  txn.readLog();
//	  txn.delelteLog();
//	  
//	} catch (IOException e) {
//	e.printStackTrace();
//	return ;
//	}
//
//try {
//	txn.commit();
//} catch (IOException e) {
//	// TODO Auto-generated catch block
//	e.printStackTrace();
//}
//return ;
//}//end main
//
//public String findResendSeq(int totalSeq){
//	String totalSeqString="";
//	for(int i=0;i<totalSeq;++i){
//		totalSeqString=totalSeqString+(new Integer(i).toString())+" ";	
//	}
//	String[] temp=receivedSequence.split("\\s+");
//	String[] temp2=totalSeqString.split("\\s+");
//	String content="";
//	if(temp2.length>temp.length){
//		for(int i=0;i<temp2.length;i++){
//			int k=0;
//			for(int j=0;j<temp.length;j++){
//			 if(!temp[j].equals(temp2[i])){
//				k++;
//			 }
//			 if(k==temp.length){
//				 content=content+temp2[i]+" ";
//			 }
//			}
//		}
//	}
//	return content;
//	
//}
